package com.mtr.databoard.common.linqlist;

import com.mongodb.lang.Nullable;

import java.util.ArrayList;
import java.util.List;

public class LinqList<T> {
    private List<T> datalist;

    public LinqList(List<T> datalist) {
        this.datalist = datalist;
    }

    public  static <M> LinqList<M> parse(List<M> list)
    {
        return  new LinqList<>(list);
    }

    public LinqList<T> where(BoolExpression<T> expression) {
        List<T> newList = new ArrayList<>();
        for (T t : datalist) {
            if (expression.call(t)) {
                newList.add(t);
            }
        }
         return new LinqList(newList);
    }

    public int count(BoolExpression<T> expression) {
        var count =0;
        if(datalist==null) return  0;
        for (T t : datalist) {
            if (expression.call(t)) {
                count+=1;
            }
        }
        return count;
    }
    public int count()
    {
        if(datalist==null) return  0;
        return  datalist.size();
    }

    public T firstOrDefault( BoolExpression<T> expression) {

        if(datalist==null||datalist.size()==0) return  null;
        if (expression == null) {
            if (datalist != null && datalist.size() > 0) return datalist.get(0);
        }

        for (T t : datalist) {
            if (expression.call(t)) {
                return t;
            }
        }
        return  null;
    }

    public <TResult>  LinqList<TResult> select( ResultExpression<T,TResult> expression) {

        if (expression == null) {
            throw new NullPointerException();
        }
        List<TResult> results = new ArrayList<>();
        for (T t : datalist) {
            TResult result =expression.call(t);
            if(result!=null) results.add(result);
        }
        return  new LinqList<>(results);
    }

    public void foreach(ObjectExpression<T> expression)
    {
        if(datalist==null) return;
        for (T t : datalist) {
            if(expression!=null)expression.call(t);
        }
    }

    public T firstOrDefault() {

        return  firstOrDefault(null);
    }

    public List<T> toList(@Nullable BoolExpression<T> expression)
    {
        if(expression!=null)
            return  where(expression).toList();
        return  datalist;
    }

    public List<T> toList()
    {
        return  toList(null);
    }
}
